#include "ChartDispatcher.h"

ChartDispatcher::ChartDispatcher(
    ControllerFactory controller_factory
    , QObject *parent
)
    : QObject(parent)
    , _controller_factory(controller_factory)
{}

ChartDispatcher::~ChartDispatcher()
{}

void ChartDispatcher::started() 
{
    auto i = _controllers.begin();
    while (i != _controllers.end())
    {
        if ((*i).isNull())
        {
            i = _controllers.erase(i);
            continue;
        }
        (*i)->started();
        ++i;
    }
}

void ChartDispatcher::paused() 
{
    for (auto controller : qAsConst(_controllers))
    {
        if (!controller) continue; 
        controller->paused();
    }
}

void ChartDispatcher::stoped()
{
    for (auto controller : qAsConst(_controllers))
    {
        if (!controller) continue; 
        controller->stoped();
    }
}

bool ChartDispatcher::acceptData(const QString &func, QVector<QString> &data)
{
    if (data.empty())
    {
        return _multiresendData(func, data);
    }

    if (func.startsWith("init") && !data.first().endsWith("set_view"))
    {
        emit initRequested(data.first());
    }

    auto plot_name_end = data.first().indexOf("@");
    if (plot_name_end <= 0)
    {
        return _resendData("@", func, data);
    }

    auto plot_name = data.first().left(plot_name_end);
    auto new_data = data;
    new_data[0] = new_data[0].remove(0, plot_name_end + 1);
    return _resendData(plot_name, func, new_data);
}

bool ChartDispatcher::_resendData(
    const QString controller_name, const QString &func, QVector<QString> &data
)
{
    auto controller_it = _controllers.find(controller_name);
    if (controller_it == _controllers.end())
    {
        QPointer<ChartController> controller = _controller_factory(
            controller_name
        );
        controller_it = _controllers.insert(
            controller_name, controller
        );
    }
    else if (!controller_it.value())
    {
        controller_it.value() = _controller_factory(controller_name);
    }

    return controller_it.value()->acceptData(func, data);
}

bool ChartDispatcher::_multiresendData(
    const QString &func, QVector<QString> &data
)
{
    bool result = false;
    for (auto controller : qAsConst(_controllers))
    {
        if (!controller) continue; 
        result = result || controller->acceptData(func, data);
    }
    return result;
}

